"""
@Author  : 康帅
@Time    : 2021/5/27 15:30
@Function: Python redis Zset使用
"""


import redis

#  使用连接池连接，避免每次建立、释放连接的开销
# redis 取出的结果默认是字节，我们可以设定 decode_responses=True 改成字符串
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)

"""
新增
zadd(name, *args, **kwargs)
"""
r.zadd("zset1", {'m1': 1, 'm2': 2})
print(r.zcard("zset1"))  # 集合长度

"""
获取有序集合元素个数 类似于len
zcard(name)
"""
print(r.zcard("zset1"))  # 集合长度

"""
获取有序集合的所有元素
r.zrange(name, start, end, desc=False, withscores=False, score_cast_func=float)
name - redis的name
start - 有序集合索引起始位置（非分数）
end - 有序集合索引结束位置（非分数）
desc - 排序规则，默认按照分数从小到大排序
withscores - 是否获取元素的分数，默认只获取元素的值
score_cast_func - 对分数进行数据转换的函数
"""
print(r.zrange("zset1", 0, -1))  # 获取有序集合中所有元素
print(r.zrange("zset1", 0, -1, withscores=True))  # 获取有序集合中所有元素和分数

"""
从大到小排序(同zrange，集合是从大到小排序的)
zrevrange(name, start, end, withscores=False, score_cast_func=float)
"""
print(r.zrevrange("zset1", 0, -1))  # 只获取元素，不显示分数
print(r.zrevrange("zset1", 0, -1, withscores=True))  # 获取有序集合中所有元素和分数,分数倒序

"""
按照分数范围获取name对应的有序集合的元素
zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
"""
for i in range(1, 30):
    element = 'n' + str(i)
    r.zadd("zset3", {element: i})
print(r.zrangebyscore("zset3", 15, 25))  # # 在分数是15-25之间，取出符合条件的元素
print(r.zrangebyscore("zset3", 12, 22, withscores=True))  # 在分数是12-22之间，取出符合条件的元素（带分数）

"""
按照分数范围获取有序集合的元素并排序（默认从大到小排序）
zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
"""
print(r.zrevrangebyscore("zset3", 22, 11, withscores=True))  # 在分数是22-11之间，取出符合条件的元素按照分数倒序

"""
获取所有元素--默认按照分数顺序排序
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
"""
print(r.zscan("zset3"))

"""
获取所有元素--迭代器
zscan_iter(name, match=None, count=None,score_cast_func=float)
"""
for i in r.zscan_iter("zset3"):  # 遍历迭代器
    print(i)

"""
zcount(name, min, max)
获取name对应的有序集合中分数 在 [min,max] 之间的个数
"""
print(r.zrange("zset3", 0, -1, withscores=True))
print(r.zcount("zset3", 11, 22))

"""
自增
zincrby(name, value, amount)
"""
r.zincrby("zset3", 2, "n2")  # 每次将n2的分数自增2
print(r.zrange("zset3", 0, -1, withscores=True))

"""
获取值的索引号
zrank(name, value)
zrevrank(name, value)，从大到小排序
"""
print(r.zrank("zset3", "n1"))  # n1的索引号是0 这里按照分数顺序（从小到大）
print(r.zrank("zset3", "n6"))  # n6的索引号是1
print(r.zrevrank("zset3", "n1"))  # n1的索引号是29 这里安照分数倒序（从大到小）

"""
删除--指定值删除
zrem(name, values)
"""
r.zrem("zset3", "n3")  # 删除有序集合中的元素n3 删除单个
print(r.zrange("zset3", 0, -1))

"""
删除--根据排行范围删除，按照索引号来删除
zremrangebyrank(name, min, max)
"""
r.zremrangebyrank("zset3", 0, 1)  # 删除有序集合中的索引号是0, 1的元素
print(r.zrange("zset3", 0, -1))

"""
删除--根据分数范围删除
zremrangebyscore(name, min, max)
"""
r.zremrangebyscore("zset3", 11, 22)  # 删除有序集合中的分数是11-22的元素
print(r.zrange("zset3", 0, -1))

"""
获取值对应的分数
zscore(name, value)
"""
print(r.zscore("zset3", "n27"))  # 获取元素n27对应的分数27
